package com.woniu.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.nimbusds.jose.JOSEException;
import com.woniu.entity.Employee;
import com.woniu.mapper.EmployeeMapper;
import com.woniu.service.EmployeeService;
import com.woniu.util.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Resource
    private EmployeeMapper employeeMapper;
    @Value("${login.salt}")
    private String loginSalt;   // 盐值

    @Resource
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 用户登录请求
     * 1：校验用户名密码是否携带
     * 2：根据用户名查询该用户信息
     * 3：对比密码是否一致
     * 4：把用户信息存入session中
     * 5：把jwt存入redis中
     */
    @Override
    public ResponseData<?> login(Employee employee) throws JOSEException {

        if (StrUtil.hasEmpty(employee.getEmployeeAccount(), employee.getLoginPassword())) {
            return ResponseData.fail(ResponseEnum.PARAM_ERROR);     // 2002，输入登录账号密码有空
        }


        // 1.验证输入是否有空
        if (StrUtil.hasEmpty(employee.getEmployeeAccount(), employee.getLoginPassword())) {
            return ResponseData.fail(ResponseEnum.PARAM_ERROR);     // 2002，输入登录账号密码有空
        }

        // 2.根据员工账号查询员工数据
        //   - 员工不存在
        //   - 员工存在，验证密码是否正确
        Employee loginEmployee = employeeMapper.queryEmployee(employee);


        if (loginEmployee == null) {    // 查询不到这个用户
            return ResponseData.fail(ResponseEnum.LOGIN_ERROR);     // 2001，员工不存在
        }

        if (loginEmployee.getStatus().equals(0)) {    // 判断用户是否离职，0代表离职
            return ResponseData.fail(ResponseEnum.NO_AUTH);         // 3000，用户未启用
        }

        // 为了密码的安全性，不能直接对明文加密后丢到数据库中
        // （密码 + 盐值）加密后再放数据库
        // 输入的密码进行md5加密
        String md5pw = SecureUtil.md5(employee.getLoginPassword() + loginSalt);
        if (!loginEmployee.getLoginPassword().equals(md5pw)) {
            return ResponseData.fail(ResponseEnum.LOGIN_ERROR);     // 2007，输入密码错误
        } else {
            // 3.输入登录数据正确
            Map map = new HashMap<>();
            map.put("employeeId", loginEmployee.getId());
            map.put("account", loginEmployee.getEmployeeAccount());
            SessionUtil.setAttribute("employee", loginEmployee);

            // 生成jwt
            String jwt = JwtUtil.createJwt(map);
            stringRedisTemplate.opsForValue().set("JWT:" + loginEmployee.getId(), jwt, 30, TimeUnit.MINUTES);
            Map resultMap = new HashMap<>();
            loginEmployee.setLoginPassword(null);
            resultMap.put("jwt", jwt);
            resultMap.put("employee", loginEmployee);
            return ResponseData.ok(resultMap);
        }
    }

    @Override
    public ResponseData<?> getSelfInfo() {
        Long userId=null;
        try {
            userId= UserContext.getContextEmpId();
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        if (userId==null) {
            return ResponseData.fail(ResponseEnum.NO_AUTH);
        }
        Employee employee = employeeMapper.queryEmployeeById(userId);
        if (employee==null) {
            return new ResponseData<>().fail(ResponseEnum.FAIL);
        } else {
            return new ResponseData<>().ok(employee);
        }
    }

    @Override
    public ResponseData<?> updateEmployee(Employee employee) {
        Integer i = employeeMapper.updateEmployee(employee);
        if (i==1) {
            return new ResponseData<>().ok(null);
        } else {
            return new ResponseData<>().fail(ResponseEnum.FAIL);
        }
    }
}
